﻿using System;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace PluginExtraction
{

    public partial class PEForm : Form
    {
        public PEForm()
        {
            InitializeComponent();
        }

        string pebuild = "Plugin Extraction Tool v1.1";

        private void btnDB_Click(object sender, EventArgs e)
        {
            comboDb.Items.Clear();
            string connectionString1 = null;


            if (isSecure.Checked)
            {
                connectionString1 = string.Format("Initial Catalog=master;Data Source={0};Integrated Security=SSPI;", txtServer.Text);
            }
            else
            {
                connectionString1 = string.Format("Initial Catalog=master;Data Source={0};user id={1};password={2};", txtServer.Text, txtUser.Text, txtPass.Text);
            }
            string queryString1 = "SELECT name FROM sysdatabases WITH (NOLOCK) WHERE name LIKE '%_MSCRM'";


            using (SqlConnection connection1 = new SqlConnection(connectionString1))
            {
                SqlCommand command1 = new SqlCommand(queryString1, connection1);
                try
                {
                    connection1.Open();
                    SqlDataReader reader1 = command1.ExecuteReader();
                    if (reader1.HasRows)
                    {
                        while (reader1.Read())
                        {
                            comboDb.Items.Add(reader1["name"]);
                        }
                        btnList.Enabled = true;
                    }
                    else
                    {
                        MessageBox.Show("No plugins found in this database", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        btnDownload.Enabled = false;
                    }
                    reader1.Close();
                }
                catch (SqlException sqlex)
                {
                    MessageBox.Show("Unable to connect to SQL Server and list databases.\n\nError: " + sqlex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (InvalidOperationException invalidex)
                {
                    MessageBox.Show("Unable to connect to SQL Server and list databases.\n\nError: " + invalidex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (Exception)
                {
                    MessageBox.Show("Unable to connect to SQL Server and list databases", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
                finally
                {
                    command1.Dispose();
                }

            }

        }

        private void btnList_Click(object sender, EventArgs e)
        {
            listBox.Items.Clear();

            if (txtServer.Text.Length <= 0)
            {
                MessageBox.Show("SQL Server is blank.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtServer.Focus();
            }

            else if (comboDb.Text.Length <= 0)
            {
                MessageBox.Show("No database is selected.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
                comboDb.Focus();
            }

            else
            {
                string org = comboDb.SelectedItem.ToString();
                string connectionString2 = null;
                string queryString2 = "SELECT name FROM PluginAssemblyBase WITH (NOLOCK) WHERE CustomizationLevel = '1'";

                if (isSecure.Checked)
                {
                    connectionString2 = string.Format("Initial Catalog={0};Data Source={1};Integrated Security=SSPI;", org, txtServer.Text);
                }
                else
                {
                    connectionString2 = string.Format("Initial Catalog={0};Data Source={1};user id={2};password={3}", org, txtServer.Text, txtUser.Text, txtPass.Text);
                }

                using (SqlConnection connection2 = new SqlConnection(connectionString2))
                {
                    SqlCommand command2 = new SqlCommand(queryString2, connection2);

                    try
                    {
                        connection2.Open();
                        SqlDataReader reader2 = command2.ExecuteReader();
                        listBox.Items.Clear();

                        if (reader2.HasRows)
                        {
                            while (reader2.Read())
                            {
                                listBox.Items.Add(reader2["Name"]);
                            }
                            btnDownload.Enabled = true;
                        }
                        else
                        {
                            MessageBox.Show("No plugins found in this database", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
                            btnDownload.Enabled = false;
                        }
                        reader2.Close();
                    }
                    catch (SqlException sqlex)
                    {
                        MessageBox.Show("Unable to connect to SQL Server and list plugins.\n\nError: " + sqlex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (InvalidOperationException invalidex)
                    {
                        MessageBox.Show("Unable to connect to SQL Server and list plugins.\n\nError: " + invalidex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("Unable to connect to SQL Server and list plugins.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        throw;
                    }
                    finally
                    {
                        command2.Dispose();
                    }
                }

            }

        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            string org = comboDb.SelectedItem.ToString();
            string connectionString3 = null;
            string queryString3 = "SELECT name, content FROM PluginAssemblyBase WITH (NOLOCK) WHERE CustomizationLevel = '1'";


            if (folderBrw.ShowDialog() == DialogResult.OK)
            {

                if (isSecure.Checked)
                {
                    connectionString3 = string.Format("Initial Catalog={0};Data Source={1};Integrated Security=SSPI;", org, txtServer.Text);
                }
                else
                {
                    connectionString3 = string.Format("Initial Catalog={0};Data Source={1};user id={2};password={3};", org, txtServer.Text, txtUser.Text, txtPass.Text);
                }

                string folder = folderBrw.SelectedPath;


                using (SqlConnection connection3 = new SqlConnection(connectionString3))
                {
                    SqlCommand command3 = new SqlCommand(queryString3, connection3);
                    command3.CommandTimeout = 5;

                    try
                    {
                        connection3.Open();
                        SqlDataReader reader3 = command3.ExecuteReader();
                        while (reader3.Read())
                        {
                            string assembly = string.Format("{0}\\{1}.dll", folder, reader3[0].ToString());
                            string content = reader3[1].ToString();
                            FileStream fs = new FileStream(assembly, FileMode.Create);
                            byte[] dll = Convert.FromBase64CharArray(content.ToCharArray(), 0, content.Length);
                            fs.Write(dll, 0, dll.Length);
                            fs.Close();
                        }
                        reader3.Close();
                        MessageBox.Show("Plugins exported successfully.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (SqlException sqlex)
                    {
                        MessageBox.Show("Unable to connect to SQL Server and extract plugins.\n\nError: " + sqlex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (InvalidOperationException invalidex)
                    {
                        MessageBox.Show("Unable to connect to SQL Server and extract plugins.\n\nError: " + invalidex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (IOException ioex)
                    {
                        MessageBox.Show("Unable to save extracted plugins to selected folder.\n\nError: " + ioex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (UnauthorizedAccessException unex)
                    {
                        MessageBox.Show("Insufficient permissions to save plugins in the selected folder.\n\nError: " + unex.Message.ToString(), pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("Unable to connect to extract plugins.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        throw;
                    }
                    finally
                    {
                        command3.Dispose();
                    }
                }

            }

        }
        private void enableListDb(object sender, EventArgs e)
        {
            if (txtServer.Text.Length > 0)
            {
                comboDb.Items.Clear();
                btnDb.Enabled = true;
            }
            else
            {
                comboDb.Items.Clear();
                listBox.Items.Clear();
                btnDb.Enabled = false;
                btnList.Enabled = false;
                btnDownload.Enabled = false;
            }
        }

        private void enableAuth(object sender, EventArgs e)
        {
            if (!isSecure.Checked)
            {
                txtPass.Enabled = true;
                txtUser.Enabled = true;
                lblUser.Enabled = true;
                lblPassword.Enabled = true;
            }
            else
            {
                txtPass.Enabled = false;
                txtPass.Clear();
                txtUser.Enabled = false;
                txtUser.Clear();
                lblUser.Enabled = false;
                lblPassword.Enabled = false;
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This tool is provided 'AS IS' without warranty of ANY kind.\n\nPlugin Extraction tool developed by mrneto@microsoft.com.", pebuild, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}
